package stud.mpgame.flash.game;

import flash.utils.IDataInput;
import stud.mpgame.flash.net.command.ArrowKeyCommand;
import stud.mpgame.network.Message;
import stud.mpgame.physics.Circle;
import stud.mpgame.physics.Vector2D;

import stud.mpgame.network.UserObject;

import stud.mpgame.snapshot.IGameObject;

/**
 * ...
 * @author pavel[f.pavel91@gmail.com]
 */
class Player extends UserObject, implements IGameObject {

	private static inline var VELOCITY:Float = 0.2;
    
    private var id:Int;
	
	private var circle:Circle;
	
	private var pressed:Array< Bool >;	
	
    public function new() {
        super();
		
		pressed = [false, false, false, false];
    }
	
	public override function readExternal(input:IDataInput, owner:Message) {
		id = input.readInt();
		
		var x:Float = input.readFloat();
		var y:Float = input.readFloat();
		
        var velocityX:Float = input.readFloat();
        var velocityY:Float = input.readFloat();
		
		circle = new Circle(x, y, 32, new Vector2D(velocityX, velocityY));		
	}
	
	public function getID():Int {
		return id;
	}
	
	public function getX():Float {
		return circle.x;
	}
	
	public function getY():Float {
		return circle.y;
	}
	
    public function applyArrowKeyCommand(arrowKeyCommand:ArrowKeyCommand):Void {
        var currentKey:Int = arrowKeyCommand.getKeyCode();
		var keyStatus:Bool = arrowKeyCommand.iskeyPressed();
		
		pressed[currentKey] = keyStatus;
		
        if ( pressed[0] )
        {
            circle.velocity.y = -1.2 * VELOCITY;
            pressed[0] = false;
        }

        if ( pressed[1] && !pressed[3] )
            circle.velocity.x = VELOCITY;
        else if ( !pressed[1] && pressed[3] )
            circle.velocity.x = -VELOCITY;
        else
            circle.velocity.x = 0;		
    }	
	
	public function getVelocityX():Float {
		return circle.velocity.x;
	}
	
	public function getVelocityY():Float {
		return circle.velocity.y;
	}
	
	public function getCircle():Circle {
		return circle;
	}
	
	public function interpolate(deltaTime:Int, gameObject:IGameObject, interpolationDeltaTime:Int):Void {		
		var serverPlayer:Player = cast(gameObject, Player);
		
		//var nx = GameUtils.interpolateDiscreteValue(circle.x, deltaTime, serverPlayer.getX(), interpolationDeltaTime);
		//var ny = GameUtils.interpolateDiscreteValue(circle.y, deltaTime, serverPlayer.getY(), interpolationDeltaTime);
		var velx:Float = (serverPlayer.circle.x - circle.x) / interpolationDeltaTime;
		var vely:Float = (serverPlayer.circle.y - circle.y) / interpolationDeltaTime;
		var nx = circle.x + deltaTime * velx;
		var ny = circle.y + deltaTime * vely;
		
		//trace("interpolate: " + circle.x + "; " + circle.y + "v: " + velx + "; " + vely + " | new(" + deltaTime + "):" + 
				//nx + "; " + ny + " | s(" + interpolationDeltaTime + "): " + serverPlayer.circle.x + "; " + serverPlayer.circle.y + 
				//" if_extra: " + (circle.x + deltaTime * circle.velocity.x) + "; " + (circle.y + deltaTime * circle.velocity.y));
		
		circle.x = nx;
		circle.y = ny;
		
		circle.velocity.x = serverPlayer.circle.velocity.x;
		circle.velocity.y = serverPlayer.circle.velocity.y;
	}
	
	public function extrapolate(deltaTime:Int):Void {
		var ox = circle.x;
		var oy = circle.y;

		circle.x += deltaTime * circle.velocity.x;
		circle.y += deltaTime * circle.velocity.y;
		/*
        //0 - up, 1 - right, 2 - down, 3 - left
        if ( pressed[0] && !pressed[2] )
            circle.y -= vel * deltaTime;
        else if ( pressed[2] && !pressed[0] )
            circle.y += vel * deltaTime;
        else if ( pressed[1] && !pressed[3] )
            circle.x += vel * deltaTime;
        else if ( pressed[3] && !pressed[1] )
            circle.x -= vel * deltaTime;		
		*/
					
		//trace("extrapolate: " + ox + "; " + oy + " v: " + circle.velocity.x + "; " + circle.velocity.y + " new: " + circle.x + "; " + circle.y);
	}
	
	public function synchronize(gameObject:IGameObject):Void {
		var player:Player = cast(gameObject, Player);
		/*
		circle.x = player.getX();
		circle.y = player.getY();
        circle.velocity.x = player.getVelocityX();
        circle.velocity.y = player.getVelocityY();
		*/
	}
    
}